package com.czk.netty.nio.mappedbytebuffer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * Scattering:将数据写入buffer时，可以采用buffer数组依次写
 * gathering:从buffer聚集
 * @Author:ChenZhangKun
 * @Date: 2021/1/11 21:21
 */
public class ScatteringAndGatheringTest {

    public static void main(String[] args) throws IOException {
        // 使用serverSocketChannel和socketChannel
        ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
        InetSocketAddress inetSocketAddress=new InetSocketAddress(7000);
        // 绑定端口
        serverSocketChannel.socket().bind(inetSocketAddress);
        // 创建buffer数组
        ByteBuffer[] byteBuffers=new ByteBuffer[2];
        ByteBuffer byteBuffer=ByteBuffer.allocate(5);
        byteBuffers[0]=byteBuffer;
        byteBuffers[1]=ByteBuffer.allocate(3);
        // 等待客户端连接
        SocketChannel socketChannel = serverSocketChannel.accept();
        int messageLength=8;
        // 循环读取
        while (true){
            int byteRead=0;
            while (byteRead<messageLength){
                // 读
                long read = socketChannel.read(byteBuffers);
                byteRead+=read;
                System.out.println("byteRead="+byteRead);
                // 使用流打印
                Arrays.asList(byteBuffers).stream().map(buffer->
                    "position="+buffer.position()+" limit="+buffer.limit()
                ).forEach(System.out::println);
            }
            // 将所有buffer翻转
            Arrays.asList(byteBuffers).stream().forEach(x->{
                x.flip();
            });
            // 将数据读出显示客户端
            long byteWrite=0;
            while (byteWrite<messageLength){
                long l = socketChannel.write(byteBuffers);
                byteWrite+=l;
            }
            // 将buffer复位
            Arrays.asList(byteBuffers).stream().forEach(x->{
                x.clear();
            });
            System.out.println("byteRead="+byteRead);
            System.out.println("byteWrite="+byteWrite);
        }
    }
}
